package net.sf.fc.io;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * Class that encapsulates a list of Files and an Options object that defines the options to
 * use when these files are copied if they are source files or when they are copied over if
 * they are destination files. The Options object can be null. If it is, the Options used are
 * defined elsewhere.
 * @author david
 *
 */
public final class FileList implements Iterable<File> {

    private final List<File> files;
    private final List<File> unmodifiableFiles;
    private final Options options;

    private volatile int hashCode = 0;

    public FileList(Options options, List<File> files) {
        if(files == null) {
            throw new IllegalArgumentException("files cannot be null.");
        }

        this.files = new ArrayList<>(files);
        unmodifiableFiles = Collections.unmodifiableList(this.files);
        this.options = options;
    }

    public FileList(List<File> files) {
        this(null, files);
    }

    public FileList(Options options, File ... files) {
        this(options, Arrays.asList(files));
    }

    public FileList(File ...files) {
        this(null, files);
    }

    public Options getOptions() { return options; }
    public List<File> getFiles() { return unmodifiableFiles; }

    @Override
    public boolean equals(Object object) {
        if(!(object instanceof FileList)) return false;
        if(object == this) return true;

        FileList that = (FileList)object;

        return this.options.equals(that.options) && this.files.equals(that.files);
    }

    @Override
    public int hashCode() {
        if(hashCode == 0) {
            int result = 17;
            result = 37*result+files.hashCode();
            if(options != null) result = 37*result+options.hashCode();
            hashCode = result;
        }
        return hashCode;
    }

    @Override
    public Iterator<File> iterator() {
        return unmodifiableFiles.iterator();
    }

}
